use log::{error, info};
use std::env;

mod tools;
use crate::tools::common;
use tools::db;
mod command;
mod app;

extern crate dirs;

use std::fs;
use std::path::Path;
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
#[tauri::command]
fn greet(name: &str) -> String {
    format!("Hello, {}! You've been greeted from Rust!", name)
}

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    init_log4rs();

    tauri::Builder::default()
        .plugin(tauri_plugin_process::init())
        .plugin(tauri_plugin_global_shortcut::Builder::new().build())
        .plugin(tauri_plugin_store::Builder::new().build())
        .plugin(tauri_plugin_updater::Builder::new().build())
        .plugin(tauri_plugin_notification::init())
        .plugin(tauri_plugin_clipboard_manager::init())
        .setup(setup_handler)
        .plugin(tauri_plugin_shell::init())
        .plugin(tauri_plugin_dialog::init())
        .invoke_handler(tauri::generate_handler![
            greet,
            command::get_all_url_class,
            command::get_url_by_class,
            command::get_all_url,
            command::save_url_form,
            command::del_url_by_id,
            command::save_class,
            command::del_class_by_id,
            command::get_all_pass_class,
            command::save_pass_item_form,
            command::refresh_pass_cache,
            command::get_all_pass,
            command::apply_pass_gen_setting,
            command::common_get_setting_item,
            command::pass_gen_pass,
            command::save_pass_class,
            command::del_pass_item,
            command::del_pass_class,
            command::todo_save,
            command::get_todo_list,
            command::done_todo,
            command::del_todo,
            app::base::app_init_success,
            app::base::get_app_init_success,
        ])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}
fn setup_handler(app: &mut tauri::App) -> Result<(), Box<dyn std::error::Error + 'static>> {
    println!("....................................");
    let home = format!(
        r"{}\{}",
        dirs::data_local_dir().unwrap().display(),
        common::APP_DIR_NAME
    );
    let path = Path::new(home.as_str());
    if !path.exists() {
        match fs::create_dir_all(&path) {
            Ok(_) => {
                log::info!("程序主目录创建成功!");
            }
            Err(e) => {
                log::error!("程序主目录创建失败!");
            }
        }
    }

    common::APP_CONFIG
        .lock()
        .unwrap()
        .insert("app_local_data_dir", home.clone());

    match db::init_db() {
        Ok(()) => {
            info!("数据库初始化完成!");
        }
        Err(e) => {
            error!("{:?}", e);
        }
    }

    Ok(())
}
fn init_log4rs() {
    use log::LevelFilter;
    use log4rs::append::console::ConsoleAppender;
    //use log4rs::append::file::FileAppender;
    use log4rs::append::rolling_file::policy::compound::{
        trigger::size::SizeTrigger, CompoundPolicy,
    };
    use log4rs::append::rolling_file::RollingFileAppender;
    use log4rs::config::{Appender, Config, Logger, Root};
    use log4rs::encode::pattern::PatternEncoder;

    let log_line_pattern = "{d(%Y-%m-%d %H:%M:%S)} | {({l}):5.5} | {f}:{L} — {m}{n}";
    let stdout = ConsoleAppender::builder()
        .encoder(Box::new(PatternEncoder::new(log_line_pattern)))
        .build();

    //单位，字节，10485760=10MB
    let trigger = Box::new(SizeTrigger::new(10485760));
    /*
    //压缩策略
    let roller = Box::new(FixedWindowRoller::builder()
        .base(roller_base)
        .build(roller_pattern, roller_count)
        .unwrap());*/
    //删除策略
    let roller =
        Box::new(log4rs::append::rolling_file::policy::compound::roll::delete::DeleteRoller::new());
    let compound_policy = Box::new(CompoundPolicy::new(trigger, roller));

    let roll_file = RollingFileAppender::builder()
        .encoder(Box::new(PatternEncoder::new(log_line_pattern)))
        .build("logs/testxxx.log", compound_policy)
        .unwrap();

    let config = Config::builder()
        .appender(Appender::builder().build("stdout", Box::new(stdout)))
        .appender(Appender::builder().build("logs", Box::new(roll_file)))
        .logger(
            Logger::builder()
                .appender("logs")
                .build("logs", LevelFilter::Debug),
        )
        .build(
            Root::builder()
                .appender("stdout")
                .appender("logs")
                .build(LevelFilter::Debug),
        )
        .unwrap();

    //log4rs::init_file("log4rs.yaml", Default::default()).unwrap();
    log4rs::init_config(config).unwrap();
}
